#include"Common.hpp"
#include"InetAddr.hpp"
#include"log.hpp"
#include<string>

using namespace LogModule;

const int defaultsockfd=-1;
const int defaultlog=8;

class TcpServer
{

    public:
    TcpServer(uint16_t port)
    :_port(port),
    _isrunning(false),
    _listensockfd(defaultsockfd)
    {

    }


    void Init()
    {
        //创建Tcp套接字
        _listensockfd=socket(AF_INET,SOCK_STREAM,0);
        if(_listensockfd<0)
        {
            LOG(LogLevel::FATAL)<<"socket create error";
            exit(ExitCode::SOCKET_ERR);
        }
        LOG(LogLevel::FATAL)<<"socket create success";

        //进行bind绑定
        InetAddr local(_port);
        int n=bind(_listensockfd,local.GetSockaddr(),local.Getlen());
        if(n!=0)
        {
            LOG(LogLevel::FATAL)<<"bind error";
            exit(ExitCode::BIND_ERR);
        }
        LOG(LogLevel::INFO)<<"bind success";

        //进行listen监听
        n=listen(_listensockfd,defaultlog);
        if(n!=0)
        {
            LOG(LogLevel::FATAL)<<"listen error";
            exit(ExitCode::LISTEN_ERR);
        }
        LOG(LogLevel::INFO)<<"listen success";


    }


    void Server(int sockfd,InetAddr& addr)
    {
        char buffer[1024];
        while(1)
        {
            ssize_t n=read(sockfd,buffer,sizeof(buffer)-1);
            if(n>0)
            {
                buffer[n]=0;
                LOG(LogLevel::INFO)<<addr.StringAddr()<<"say#"<<buffer;
                std::string echo_string ="echo#"+std::string(buffer);
                ssize_t wn=write(sockfd,echo_string.c_str(),echo_string.size());
                LOG(LogLevel::INFO) << "write返回值: " << wn;
            }
            else if(n==0)
            {
                LOG(LogLevel::DEBUG)<<addr.StringAddr()<<"退出……";
                close(sockfd);
                break;
            }
            else{
                LOG(LogLevel::FATAL)<<addr.StringAddr()<<"读取失败";
                close(sockfd);
                break;
            }

        }



    }

    void Run()
    {
        _isrunning=true;
        while(true)
        {
            //进行获取连接
            sockaddr_in addr;
            socklen_t len=sizeof(addr);
            int sockfd=accept(_listensockfd,COW(addr),&len);
            if(sockfd<0)
            {
                LOG(LogLevel::WARNING)<<"accept error";
                continue;
            }
            InetAddr peer(addr);
            LOG(LogLevel::INFO)<<peer.StringAddr()<<"accept success";
            
            Server(sockfd,peer);


        }
    }



    private:

    int _listensockfd;
    uint16_t _port;
    bool _isrunning;


};
